/*
 * Copyright (c) 2024 Shenzhen Kaihong Digital Industry Development Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "sle_connect_config_manager.h"

namespace OHOS {
namespace NearLink {
namespace SleStandard {
namespace {
constexpr const char *CONNECT_CONFIG_COMMON = "sle_connect_config_common";
constexpr const char *CONNECT_CONFIG_PARAM_SECTION = "sle_connect_config_mode";
constexpr const char *CONNECT_CONFIG_DEFAULT_PARAM = "sle_connect_config_default_param";
}

SleConnectConfigManager::SleConnectConfigManager()
{
    SLE_ASSERT_AND_RETURN(fileName_.empty() == false);
    connectCfg_ = std::make_unique<SleConnectConfig>();
    connectModeCfg_ = std::make_unique<SleConnectModeConfig>();
    connectDefaultCfg_ = std::make_unique<SleDefaultConnectionParam>();
    sleCfgMgr_ = std::make_unique<SleConfigManager>(fileName_);
    SLE_ASSERT_AND_RETURN_LOG(sleCfgMgr_ != NULL, "create sleCfgMgr_ fail");
    SLE_ASSERT_AND_RETURN(GetDefaultConfigFromValues() == SLE_NO_ERROR);
    SLE_ASSERT_AND_RETURN(GetConfigModeFromValues() == SLE_NO_ERROR);
    SLE_ASSERT_AND_RETURN(GetConfigFromValues() == SLE_NO_ERROR);
}

SleConnectConfigManager::SleConnectConfigManager(std::string fileName)
{
    SLE_ASSERT_AND_RETURN(fileName.empty() == false);
    fileName_ = fileName;
    connectCfg_ = std::make_unique<SleConnectConfig>();
    connectModeCfg_ = std::make_unique<SleConnectModeConfig>();
    connectDefaultCfg_ = std::make_unique<SleDefaultConnectionParam>();
    sleCfgMgr_ = std::make_unique<SleConfigManager>(fileName_);
    SLE_ASSERT_AND_RETURN_LOG(sleCfgMgr_ != NULL, "create sleCfgMgr_ fail");
    SLE_ASSERT_AND_RETURN(GetDefaultConfigFromValues() == SLE_NO_ERROR);
    SLE_ASSERT_AND_RETURN(GetConfigModeFromValues() == SLE_NO_ERROR);
    SLE_ASSERT_AND_RETURN(GetConfigFromValues() == SLE_NO_ERROR);
}

SleConnectConfigManager::~SleConnectConfigManager()
{
//    SleErrorCode ret = SetConfigToValues();
//    SLE_ASSERT_AND_RETURN(ret == SLE_NO_ERROR);
//    SLE_ASSERT_AND_RETURN(SetConfigToValues() == SLE_NO_ERROR);
}

SleErrorCode SleConnectConfigManager::GetConnectConfig(SleConnectConfig &connectConfig)
{
    SLE_ASSERT_AND_RETURN_RET(connectCfg_ != NULL, SLE_ERR_NOT_READY);
    connectConfig = *connectCfg_.get();
    return SLE_NO_ERROR;
}

SleErrorCode SleConnectConfigManager::GetConnectLocalModeConfig(SleConnectModeConfig &modeConfig)
{
    SLE_ASSERT_AND_RETURN_RET(connectModeCfg_ != NULL, SLE_ERR_NOT_READY);
    modeConfig = *connectModeCfg_.get();
    return SLE_NO_ERROR;
}

SleErrorCode SleConnectConfigManager::GetConnectMode(std::string &mode)
{
    mode = CONNECT_CONFIG_PARAM_SECTION + std::to_string(connectModeCfg_->configMode);
    SLE_LOGD("GetConnectMode mode = %{public}s", mode.c_str());
    return SLE_NO_ERROR;
}

SleErrorCode SleConnectConfigManager::GetConnectDefaultConfig(SleDefaultConnectionParam &defaultConfig)
{
    SLE_ASSERT_AND_RETURN_RET(connectDefaultCfg_ != NULL, SLE_ERR_NOT_READY);
    defaultConfig = *connectDefaultCfg_.get();
    return SLE_NO_ERROR;
}

SleErrorCode SleConnectConfigManager::GetDefaultConfigFromValues()
{
    SleConfigValueMap valueMap;
    SleErrorCode ret = sleCfgMgr_->GetValue(valueMap);
    std::string modeCfg = CONNECT_CONFIG_DEFAULT_PARAM;
    SleConfigValue values = valueMap[modeCfg];
    SLE_ASSERT_AND_RETURN_RET(ret == SLE_NO_ERROR, ret);
    connectDefaultCfg_->enable_filter_policy = sleCfgMgr_->Str2Uint8(values["enable_filter_policy"]);
    connectDefaultCfg_->initiate_phys = sleCfgMgr_->Str2Uint8(values["initiate_phys"]);
    connectDefaultCfg_->gt_negotiate = sleCfgMgr_->Str2Uint8(values["gt_negotiate"]);
    connectDefaultCfg_->scan_interval = sleCfgMgr_->Str2Uint16(values["scan_interval"]);
    connectDefaultCfg_->scan_window = sleCfgMgr_->Str2Uint16(values["scan_window"]);
    connectDefaultCfg_->min_interval = sleCfgMgr_->Str2Uint16(values["min_interval"]);
    connectDefaultCfg_->max_interval = sleCfgMgr_->Str2Uint16(values["max_interval"]);
    connectDefaultCfg_->timeout = sleCfgMgr_->Str2Uint16(values["timeout"]);
    return SLE_NO_ERROR;
}

SleErrorCode SleConnectConfigManager::GetConfigModeFromValues()
{
    SleConfigValueMap valueMap;
    SleErrorCode ret = sleCfgMgr_->GetValue(valueMap);
    std::string modeCfg = CONNECT_CONFIG_COMMON;
    SleConfigValue values = valueMap[modeCfg];
    SLE_ASSERT_AND_RETURN_RET(ret == SLE_NO_ERROR, ret);
    connectModeCfg_->workMode = sleCfgMgr_->Str2Uint8(values["workMode"]);
    connectModeCfg_->stepCount = sleCfgMgr_->Str2Uint16(values["stepCount"]);
    connectModeCfg_->stepPeriod = sleCfgMgr_->Str2Uint16(values["stepPeriod"]);
    connectModeCfg_->configMode = sleCfgMgr_->Str2Uint8(values["configMode"]);
    return SLE_NO_ERROR;
}

SleErrorCode SleConnectConfigManager::GetConfigFromValues()
{
    SleConfigValueMap valueMap;
    SleErrorCode ret = sleCfgMgr_->GetValue(valueMap);
    std::string modeStr;
    GetConnectMode(modeStr);
    SleConfigValue values = valueMap[modeStr];
    SLE_ASSERT_AND_RETURN_RET(ret == SLE_NO_ERROR, ret);
    connectCfg_->connectInterval = sleCfgMgr_->Str2Uint16(values["connectInterval"]);
    connectCfg_->connectTimeout = sleCfgMgr_->Str2Uint16(values["connectTimeout"]);
    connectCfg_->connectLatency = sleCfgMgr_->Str2Uint16(values["connectLatency"]);
    connectCfg_->mtuSize = sleCfgMgr_->Str2Uint32(values["mtuSize"]);
    connectCfg_->mcs = sleCfgMgr_->Str2Uint8(values["mcs"]);
    connectCfg_->pilotDensity = sleCfgMgr_->Str2Uint8(values["pilotDensity"]);
    connectCfg_->formatType = sleCfgMgr_->Str2Uint8(values["formatType"]);
    connectCfg_->dataLen = sleCfgMgr_->Str2Uint16(values["dataLen"]);
    connectCfg_->phy = sleCfgMgr_->Str2Uint8(values["phy"]);
    return SLE_NO_ERROR;
}

SleErrorCode SleConnectConfigManager::SetConfigToValues()
{
    SleConfigValue values;
    values["connectInterval"] = std::to_string(connectCfg_->connectInterval);
    values["connectTimeout"] = std::to_string(connectCfg_->connectTimeout);
    values["mtuSize"] = std::to_string(connectCfg_->mtuSize);
    values["connectLatency"] = std::to_string(connectCfg_->connectLatency);
    values["mcs"] = std::to_string(connectCfg_->mcs);
    values["pilotDensity"] = std::to_string(connectCfg_->pilotDensity);
    values["formatType"] = std::to_string(connectCfg_->formatType);
    values["dataLen"] = std::to_string(connectCfg_->dataLen);
    values["phy"] = std::to_string(connectCfg_->phy);
    std::string modeStr;
    GetConnectMode(modeStr);
    SleConfigValueMap valueMap;
    valueMap[modeStr] = values;
    SleErrorCode ret = sleCfgMgr_->SetValue(valueMap);
    SLE_ASSERT_AND_RETURN_RET(ret == SLE_NO_ERROR, ret);
    return SLE_NO_ERROR;
}

} // SleStandard
} // NearLink
} // OHOS